﻿using Microsoft.SharePoint;
using Microsoft.SharePoint.Administration;
using Microsoft.SharePoint.Utilities;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Xml;

namespace RioLinx.SharePoint.Publishing.Library
{
    public class FileManager
    {

        static bool bQuietMode = false;

        public static void RefreshPageFromLayout(string strSiteUrl, string strPageLibraryName, string strPageName, string strTemplateLibraryName, string strPageDisplayTitle, bool bUsePublishing)
        {
            using (SPSite spSite = new SPSite(strSiteUrl))
            {
                using (SPWeb spWeb = spSite.OpenWeb())
                {
                    string sourceFilePath;
                    string content;

                    // Assuming the Web Part Page template has a Title Bar Web Part with the title place holder "_TitlePlaceHolder_"
                    //content = content.Replace("_TitlePlaceHolder_", strPageName);
                    // Save the target file into the database
                    strPageName += ".aspx";

                    //SPSite spSite = new SPSite(strSiteUrl);
                    //SPWeb spWeb = spSite.OpenWeb();

                    //string doclibID = onetidDocLibIDSelect.Value;
                    //Guid guidDocLib = new Guid(doclibID);
                    SPList doclib = spWeb.Lists[strPageLibraryName];
                    string folderPath = doclib.RootFolder.Url;
                    string targetFilePath = spWeb.Url + "/" + folderPath + "/" + strPageName;

                    SPFile spFile = spWeb.GetFile(targetFilePath);
                    bool bExists = spFile.Exists;

                    if (bExists)
                    {

                        SPListItem fileItem = spFile.Item;
                        string strPageTemplateName = fileItem["PublishingPageTemplate"] as string;

                        if (bUsePublishing)
                        {
                            //Get template from library
                            SPWeb rootWeb = spSite.RootWeb;
                            SPList layoutLib = rootWeb.Lists[strTemplateLibraryName];
                            string layoutFolderPath = layoutLib.RootFolder.Url;
                            sourceFilePath = rootWeb.Url + "/" + layoutFolderPath + "/" + strPageTemplateName;
                            SPFile sourceFile = rootWeb.GetFile(sourceFilePath);

                            using (StreamReader reader = new StreamReader(sourceFile.OpenBinaryStream()))
                            {
                                content = reader.ReadToEnd();
                            }
                            rootWeb.Dispose();
                        }
                        else
                        {
                            sourceFilePath = SPUtility.GetVersionedGenericSetupPath("Template", 15) + "\\Layouts\\RWD\\PageTemplates\\";
                            sourceFilePath += strPageTemplateName;

                            System.IO.StreamReader sr = new System.IO.StreamReader(sourceFilePath);

                            content = sr.ReadToEnd();
                        }

                        // Convert the string into UTF8 encoded bytes
                        System.Text.UTF8Encoding encoding = new System.Text.UTF8Encoding();
                        System.Byte[] contentBytes = encoding.GetBytes(content);
                        System.Byte[] bytes = new System.Byte[contentBytes.Length + 3];
                        // Adding UTF8 byte order mark
                        bytes[0] = 0xEF;
                        bytes[1] = 0xBB;
                        bytes[2] = 0xBF;
                        contentBytes.CopyTo(bytes, 3);

                        SPFile page = null;
                        SPFileCollection fileCollection = spWeb.Files;
                        page = fileCollection.Add(targetFilePath, bytes, true);
                        page = fileCollection.Add(spFile.Url, bytes, true);

                        //if (spFile == null || !bExists)
                        //{
                        //    AddTestWebParts(spWeb, page);
                        //}

                        // Add PageDisplayTitle
                        if (!string.IsNullOrEmpty(strPageDisplayTitle))
                        {
                            try
                            {
                                SPListItem item = page.Item;
                                item["PageDisplayTitle"] = strPageDisplayTitle;
                                item.Update();
                            }
                            catch (Exception)
                            {

                                //throw;
                            }

                        }
                        // Add PageResponsiveTemplate
                        if (!string.IsNullOrEmpty(strPageTemplateName))
                        {
                            try
                            {
                                SPListItem item = page.Item;
                                item["PageTemplate"] = "verification" + strPageTemplateName;
                                item.Update();
                            }
                            catch (Exception)
                            {

                                //throw;
                            }

                        }
                    }

                }
            }
        }

        //Used to refresh page layout (on page, with layout template picker)
        public static void RefreshPageFromLayout(SPListItem fileItem, string strSourceFilePath, bool bUsePublishing)
        {
            string strPageTemplateName;
            string content;

            SPFile spFile = fileItem.File;
            bool bExists = spFile.Exists;

            if (bExists)
            {
                if (bUsePublishing)
                {
                    //Get template from library
                    SPWeb rootWeb = fileItem.Web.Site.RootWeb;
                    SPFile sourceFile = rootWeb.GetFile(strSourceFilePath);
                    strPageTemplateName = sourceFile.Name;

                    using (StreamReader reader = new StreamReader(sourceFile.OpenBinaryStream()))
                    {
                        content = reader.ReadToEnd();
                    }
                    rootWeb.Dispose();
                }
                else
                {
                    strPageTemplateName = fileItem["PublishingPageTemplate"] as string;
                    string sourceFilePath = SPUtility.GetVersionedGenericSetupPath("Template", 15) + "\\Layouts\\RWD\\PageTemplates\\";
                    sourceFilePath += strPageTemplateName;

                    System.IO.StreamReader sr = new System.IO.StreamReader(sourceFilePath);

                    content = sr.ReadToEnd();
                }

                // Convert the string into UTF8 encoded bytes
                System.Text.UTF8Encoding encoding = new System.Text.UTF8Encoding();
                System.Byte[] contentBytes = encoding.GetBytes(content);
                System.Byte[] bytes = new System.Byte[contentBytes.Length + 3];
                // Adding UTF8 byte order mark
                bytes[0] = 0xEF;
                bytes[1] = 0xBB;
                bytes[2] = 0xBF;
                contentBytes.CopyTo(bytes, 3);

                SPFile page = null;
                SPFileCollection fileCollection = fileItem.Web.Files;
                page = fileCollection.Add(spFile.Url, bytes, true);

                // Add PageResponsiveTemplate
                if (!string.IsNullOrEmpty(strPageTemplateName))
                {
                    try
                    {
                        SPListItem item = page.Item;
                        item["PublishingPageTemplate"] = strPageTemplateName;
                        item.Update();
                    }
                    catch (Exception)
                    {
                        //throw;
                    }

                }

            }
        }

        //Used to refresh list pages layout (loop)
        public static void RefreshListPageFromLayout(SPListItem fileItem, string strTemplateLibraryName, bool bUsePublishing)
        {
            //using (SPSite spSite = new SPSite(strSiteUrl))
            //{
            //    using (SPWeb spWeb = spSite.OpenWeb())
            //    {
            string sourceFilePath;
            string content;


            SPFile spFile = fileItem.File;

            bool bExists = spFile.Exists;

            if (bExists)
            {

                string strPageTemplateName = fileItem["PublishingPageTemplate"] as string;

                if (bUsePublishing)
                {
                    //Get template from library
                    SPWeb rootWeb = fileItem.Web.Site.RootWeb;
                    SPList layoutLib = rootWeb.Lists[strTemplateLibraryName];
                    string layoutFolderPath = layoutLib.RootFolder.Url;
                    sourceFilePath = rootWeb.Url + "/" + layoutFolderPath + "/" + strPageTemplateName;
                    SPFile sourceFile = rootWeb.GetFile(sourceFilePath);

                    using (StreamReader reader = new StreamReader(sourceFile.OpenBinaryStream()))
                    {
                        content = reader.ReadToEnd();
                    }
                    rootWeb.Dispose();
                }
                else
                {
                    sourceFilePath = SPUtility.GetVersionedGenericSetupPath("Template", 15) + "\\Layouts\\RWD\\PageTemplates\\";
                    sourceFilePath += strPageTemplateName;

                    System.IO.StreamReader sr = new System.IO.StreamReader(sourceFilePath);

                    content = sr.ReadToEnd();
                }

                // Convert the string into UTF8 encoded bytes
                System.Text.UTF8Encoding encoding = new System.Text.UTF8Encoding();
                System.Byte[] contentBytes = encoding.GetBytes(content);
                System.Byte[] bytes = new System.Byte[contentBytes.Length + 3];
                // Adding UTF8 byte order mark
                bytes[0] = 0xEF;
                bytes[1] = 0xBB;
                bytes[2] = 0xBF;
                contentBytes.CopyTo(bytes, 3);

                SPFile page = null;
                SPFileCollection fileCollection = fileItem.Web.Files;
                page = fileCollection.Add(spFile.Url, bytes, true);

                //if (spFile == null || !bExists)
                //{
                //    AddTestWebParts(spWeb, page);
                //}


            }
        }



        //Used to refresh all the pages layout
        public static void RefreshAllLayout(string strSiteUrl, string strPageLibraryName, string strTemplateLibraryName, bool bUsePublishing)
        {
            SPSite spSite = new SPSite(strSiteUrl);
            ProcessSiteCollection(spSite, strPageLibraryName, strTemplateLibraryName, bUsePublishing);   
        }

        static void ProcessSiteCollection(SPSite spSite, string strPageLibraryName, string strTemplateLibraryName, bool bUsePublishing)
        {
            if (!bQuietMode)
            {
                Console.WriteLine(string.Format("---- Processing Site Collection {0} -----", spSite.Url));
            }
            SPWeb spWeb = spSite.OpenWeb();
            //SPWeb rootWeb = spSite.RootWeb;

            ProcessSite(spSite, spWeb, strPageLibraryName, strTemplateLibraryName, bUsePublishing);

            spWeb.Dispose();
            //rootWeb.Dispose();

        }

        static void ProcessSite(SPSite spSite, SPWeb spWeb, string strPageLibraryName, string strTemplateLibraryName, bool bUsePublishing)
        {
            if (!bQuietMode)
            {
                Console.WriteLine(string.Format("---- Processing Site {0}-----", spWeb.Url));
            }

            //Root 
            RefreshLayout(spSite, spWeb, strPageLibraryName, strTemplateLibraryName, bUsePublishing);

            //Boucle 
            if (spWeb.Webs != null && spWeb.Webs.Count > 0)
            {
                foreach (SPWeb subWeb in spWeb.Webs)
                {
                    ProcessSite(spSite, subWeb, strPageLibraryName, strTemplateLibraryName, bUsePublishing);
                    subWeb.Dispose();
                }
            }
        }

        //Method called in RefreshAllLayout, used to refresh all the pages layout of the current web site.
        static void RefreshLayout(SPSite spSite, SPWeb spWeb, string strPageLibraryName, string strTemplateLibraryName, bool bUsePublishing)
        {
            SPList doclib = spWeb.Lists[strPageLibraryName];
            SPListItemCollection collItem = doclib.Items;

            foreach (SPListItem item in collItem)
            {
                string strPageTemplateName = item["PublishingPageTemplate"] as string;

                if (strPageTemplateName != null) { 
                    FileManager.RefreshListPageFromLayout(item, strTemplateLibraryName, bUsePublishing);
                }
            }         

        }

    }
}
